package org.dtrd.modules.patient.controller;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.dtrd.base.BaseController;
import org.dtrd.common.api.vo.Result;
import org.dtrd.common.system.util.JwtUtil;
import org.dtrd.config.system.Constant;
import org.dtrd.modules.base.service.BaseCommonService;
import org.dtrd.modules.patient.entity.bean.report.*;
import org.dtrd.modules.patient.entity.po.DtrdEntRdReport;
import org.dtrd.modules.patient.entity.request.PatientReportIndexRequest;
import org.dtrd.modules.patient.service.IDtrdEntRdPatientService;
import org.dtrd.modules.patient.service.IDtrdEntRdReportService;
import org.dtrd.modules.service.entity.po.DtrdRlPackagePatient;
import org.dtrd.modules.service.service.IDtrdEntRdServicePackageService;
import org.dtrd.modules.service.service.IDtrdRlPackagePatientService;
import org.dtrd.modules.util.ReportUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

import static org.dtrd.common.constant.CommonConstant.*;
import static org.dtrd.config.system.SystemState.ResponseState.*;

/**
 * @author qr
 * @date 2022/1/18 13:38
 */
@RestController
@RequestMapping("/patient/report")
@Api(tags = "患者报告")
public class PatientReportController extends BaseController {

    @Autowired
    private IDtrdEntRdReportService reportService;
    @Autowired
    private BaseCommonService baseCommonService;
    @Autowired
    private IDtrdEntRdPatientService patientService;
    @Autowired
    private IDtrdRlPackagePatientService packagePatientRlService;
    @Autowired
    private IDtrdEntRdServicePackageService packageService;

    @ApiOperation(value = "获取患者报告首页内容", notes = "手机端", response = PatientReportIndex.class)
    @PostMapping("/index")
    public Result<?> getPatientReportIndex(@RequestBody PatientReportIndexRequest request) {
        Integer patientId = request.getPatientId();
        if (patientId == null) {
            return error(STATE_PARAMS_MISSING);
        }
        if (request.getQueryDateMonth() == null) {
            request.setQueryDateMonth(new Date());
        }
        if (request.getQueryDateWeek() == null) {
            request.setQueryDateWeek(new Date());
        }
        PatientReportIndex index = reportService.getPatientReportIndex(patientId, request.getQueryDateWeek(), request.getQueryDateMonth());
        return Result.OK(index);
    }

    @ApiOperation(value = "创建并获取周报的接口", response = ReportWeek.class)
    @GetMapping("/week/create")
    public Result<?> getWeekReport(@RequestParam Integer patientId) {
        String packageName = packageService.getServingPackageName(patientId);
        // 如果根据Id获取不到用户的服务包名，直接返回错误（暂时还没修改）
        String reportName = ReportUtil.getReportWeekName(packageName);
        ReportWeek reportWeek = reportService.createReportWeek(patientId, reportName);
        return Result.OK(reportWeek);
    }

    @ApiOperation(value = "创建并获取月报的接口", response = ReportWeek.class)
    @GetMapping("/month/create")
    public Result<?> getMonthReport(@RequestParam Integer patientId) {
        String packageName = packageService.getServingPackageName(patientId);
        // 如果根据Id获取不到用户的服务包名，直接返回错误（暂时还没修改）
        String reportName = ReportUtil.getReportMonthName(packageName);
        ReportMonth reportMonth = reportService.createReportMonth(patientId, reportName);
        return Result.OK(reportMonth);
    }

    @ApiOperation(value = "生成首诊报告（新）", response = PatientReport.class, notes = "只能手动生成首诊报告和总结报告")
    @PostMapping("/first/create")
    public Result<?> createFirstReport(@RequestBody CreateReportBean request,
                                  HttpServletRequest httpServletRequest) {
        Integer patientId = request.getPatientId();
        String token = httpServletRequest.getHeader("X-Access-Token");
        String username = null;
        if (StrUtil.isNotBlank(token)) {
            username = JwtUtil.getUsername(token);
        }
        reportService.createReportFirstV2(patientId, username);
        String logContent = String.format("生成患者报告, patientId：%d, type: %s", patientId, "首诊报告");
        baseCommonService.addLog(logContent, OPERATE_TYPE_ADD);
        return Result.OK();
    }

    @ApiOperation(value = "更新首诊报告内容并发布（新）", response = PatientReport.class, notes = "只能手动生成首诊报告和总结报告")
    @PostMapping("/first/update")
    public Result<?> updateFirstReportContent(@RequestBody @Validated ReportFirstUpdateRequest request,
                                         HttpServletRequest httpServletRequest){
        Integer reportId = request.getReportId();
        if (reportId == null) {
            return error(STATE_PARAMS_MISSING);
        }
        String name = JwtUtil.getUserNameByToken(httpServletRequest);
        boolean result = reportService.updateFirstReportContent(request, name);
        String logContent = String.format("更新报告内容, 报告id: %d", reportId);
        baseCommonService.addLog(logContent, OPERATE_TYPE_UPDATE);
        return result ? Result.OK() : error(STATE_OPERATION_FAILURE);
    }

    @ApiOperation(value = "更新周报报告内容并发布（新）", response = ReportWeek.class, notes = "更新周报的输入字段，并发布周报")
    @PostMapping("/week/update")
    public Result<?> updateWeekReportContent(@RequestBody @Validated ReportWeekUpdateRequest request,
                                              HttpServletRequest httpServletRequest){
        Integer reportId = request.getReportId();
        if (reportId == null) {
            return error(STATE_PARAMS_MISSING);
        }
        String name = JwtUtil.getUserNameByToken(httpServletRequest);
        boolean result = reportService.updateWeekReportContent(request, name);
        String logContent = String.format("更新周报报告内容, 报告id: %d", reportId);
        baseCommonService.addLog(logContent, OPERATE_TYPE_UPDATE);
        return result ? Result.OK() : error(STATE_OPERATION_FAILURE);
    }

    @ApiOperation(value = "更新月报报告内容并发布（新）", response = ReportMonth.class, notes = "更新月报的输入字段，并发布月报")
    @PostMapping("/month/update")
    public Result<?> updateMonthReportContent(@RequestBody @Validated ReportMonthUpdateRequest request,
                                             HttpServletRequest httpServletRequest){
        Integer reportId = request.getReportId();
        if (reportId == null) {
            return error(STATE_PARAMS_MISSING);
        }
        String name = JwtUtil.getUserNameByToken(httpServletRequest);
        boolean result = reportService.updateMonthReportContent(request, name);
        String logContent = String.format("更新周报报告内容, 报告id: %d", reportId);
        baseCommonService.addLog(logContent, OPERATE_TYPE_UPDATE);
        return result ? Result.OK() : error(STATE_OPERATION_FAILURE);
    }

    @ApiOperation(value = "生成报告", response = PatientReport.class, notes = "只能手动生成首诊报告和总结报告")
    @PostMapping("/create")
    public Result<?> createReport(@RequestBody CreateReportBean request,
                                  HttpServletRequest httpServletRequest) {
        Integer patientId = request.getPatientId();
        Integer type = request.getType();
        DtrdRlPackagePatient patientPackage = packagePatientRlService.getLatestPatientPackage(patientId);
        if (patientPackage == null) {
            return Result.error("患者尚未设置服务!");
        }
        //   region 方便调试先不限定
        //   if (type.equals(Constant.ReportType.REPORT_SUMMARY.getType()) &&
        //        !packagePatientRlService.hasFinishedServicePackage(patientId)) {
        //        return Result.error("服务尚未结束");
        //   }
        //   endregion
        String token = httpServletRequest.getHeader("X-Access-Token");
        String username = null;
        if (StrUtil.isNotBlank(token)) {
            username = JwtUtil.getUsername(token);
        }
        Constant.ReportType reportType = Constant.ReportType.valueOf(type);
        switch (reportType) {
            case REPORT_FIRST:
                reportService.createReportFirst(patientId, username);
                break;
            case REPORT_SUMMARY:
                reportService.createReportSummary(patientId, username);
                break;
            default:
                break;
        }
        String logContent = String.format("生成患者报告, patientId：%d, type: %d", patientId, type);
        baseCommonService.addLog(logContent, OPERATE_TYPE_ADD);
        return Result.OK();
    }

    @ApiOperation(value = "获取患者首诊报告", response = ReportFirst.class)
    @GetMapping("first")
    public Result<?> getFirstReport(@RequestParam Integer patientId) {
        ReportFirst firstReport = reportService.getPatientFirstReport(patientId, Constant.ReportType.REPORT_FIRST.getType());
        String logContent = String.format("获取患者的首诊报告, patientId：%d", patientId);
        baseCommonService.addLog(logContent, OPERATE_TYPE_QUERY);
        return firstReport != null ? Result.OK(firstReport) : error(STATE_NO_RECORD);
    }

    @ApiOperation(value = "获取患者总结报告", response = ReportSummary.class)
    @GetMapping("summary")
    public Result<?> getSummaryReport(@RequestParam Integer patientId) {
        ReportSummary summaryReport = reportService.getPatientSummaryReport(patientId);
        String logContent = String.format("获取患者的总结报告, patientId：%d", patientId);
        baseCommonService.addLog(logContent, OPERATE_TYPE_QUERY);
        return Result.OK(summaryReport);
    }

    @ApiOperation("发布报告")
    @PostMapping("publish")
    public Result<?> publishReport(@RequestBody ReportPublishRequest request,
                                   HttpServletRequest httpServletRequest) {
        Integer reportId = request.getReportId();
        Integer publishStatus = request.getPublishStatus();
        if (reportId == null || publishStatus == null || StrUtil.isBlank(request.getSummary())) {
            return error(STATE_PARAMS_MISSING);
        }
        DtrdEntRdReport report = reportService.getById(reportId);
        if (report == null) {
            return error(STATE_PARAMS_ERROR);
        }
        report.setPublishStatus(publishStatus);
        report.setSummary(request.getSummary());
        report.setPublishTime(new Date());
        // 设置发布人姓名
        report.setPublisher(JwtUtil.getUserNameByToken(httpServletRequest));
        boolean result = reportService.updateById(report);
        String logContent = String.format("设置报告的发布状态, 报告id: %d, 报告状态: %d", reportId, publishStatus);
        baseCommonService.addLog(logContent, OPERATE_TYPE_UPDATE);
        return result ? Result.OK() : error(STATE_OPERATION_FAILURE);
    }

    @ApiOperation("更新总结报告内容")
    @PostMapping("summary/update")
    public Result<?> updateReportContent(@RequestBody ReportSummaryUpdateRequest request,
                                         HttpServletRequest httpServletRequest){
        Integer reportId = request.getReportId();
        if (reportId == null) {
            return error(STATE_PARAMS_MISSING);
        }
        String name = JwtUtil.getUserNameByToken(httpServletRequest);
        boolean result = reportService.updateSummaryReportContent(request, name);
        String logContent = String.format("更新报告内容, 报告id: %d", reportId);
        baseCommonService.addLog(logContent, OPERATE_TYPE_UPDATE);
        return result ? Result.OK() : error(STATE_OPERATION_FAILURE);
    }


    @ApiOperation(value = "查询患者周报详情", response = ReportWeek.class)
    @GetMapping("week/get")
    public Result<?> getWeekReportDetail(@RequestParam Integer id) {
        if (isIntParamInvalid(id)) {
            return error(STATE_PARAMS_ERROR);
        }
        ReportWeek reportWeek = reportService.getWeeklyReport(id);
        String logContent = String.format("查询患者周报报告详情，查询id：%d", id);
        baseCommonService.addLog(logContent, OPERATE_TYPE_QUERY);
        return reportWeek != null ? Result.OK(reportWeek) : error(STATE_NO_RECORD);
    }

    @ApiOperation(value = "查询患者月报详情", response = ReportMonth.class)
    @GetMapping("month/get")
    public Result<?> getMonthReportDetail(@RequestParam Integer id) {
        if (isIntParamInvalid(id)) {
            return error(STATE_PARAMS_ERROR);
        }
        ReportMonth reportWeek = reportService.getMonthReport(id);
        String logContent = String.format("查询患者月报报告详情，查询id：%d", id);
        baseCommonService.addLog(logContent, OPERATE_TYPE_QUERY);
        return reportWeek != null ? Result.OK(reportWeek) : error(STATE_NO_RECORD);
    }

    @ApiOperation(value = "分页查询患者报告列表", response = ReportListInfo.class)
    @PostMapping("page")
    public Result<?> getReportList(@RequestBody ReportPageRequest request) {
        Integer type = request.getType();
        Integer patientId = request.getPatientId();
        if (type == null || patientId == null) {
            return error(STATE_PARAMS_MISSING);
        }
        Integer size = getPageSize(request.getPageSize(), 10);
        Integer num = getIntParam(request.getPageNum(), 1);
        request.setPageSize(size);
        request.setPageNum(num);
        IPage<ReportListInfo> page = reportService.pageReport(request);
        String logContent = String.format("分页查询患者报告列表, 患者id: %d, 报告类型: %d", patientId, type);
        baseCommonService.addLog(logContent, OPERATE_TYPE_QUERY);
        return Result.OK(wrapperPage(page));
    }


    @ApiOperation("删除患者报告")
    @DeleteMapping("remove")
    public Result<?> removeReport(@RequestParam Integer id) {
        if (isIntParamInvalid(id)) {
            return error(STATE_PARAMS_MISSING);
        }
        boolean result = reportService.removeReport(id);
        String logContent = String.format("删除患者报告, 删除id: %d", id);
        baseCommonService.addLog(logContent, OPERATE_TYPE_DELETE);
        return result ? Result.OK() : error(STATE_OPERATION_FAILURE);
    }
}
